#!/usr/bin/env python
# coding: utf-8

# In[94]:


import matplotlib
import matplotlib.pyplot as plt
import numpy as np
import wave

class Wav_FFT(object):
    '''
    对音频数据做fft，然后判断是否是人类的声音。
    '''
    def __init__(self, wav_path=''):
        self.path = wav_path
        
    def read_wav(self):
        with  wave.open(self.path, "rb") as f:
            parameters = f.getparams()
            self.nchannels, self.sampwidth, self.framerate, self.nframes = parameters[:4]
            self.time_len = self.nframes*1.0 / self.framerate #声音时长
            print("声道数: ", self.nchannels) #声道数：可以是单声道或者是双声道
            print("量化位数[byte]: ", self.sampwidth)#量化位数：一次采样所采集的数据的字节数
            print("采样频率[Hz]: ", self.framerate) #采样频率：一秒内对声音信号的采集次数，常用的有8kHz, 16kHz, 32kHz, 48kHz, 11.025kHz, 22.05kHz, 44.1kHz
            print("采样点数: ", self.nframes)#采样点数
            print("声音时长[s]: ", round(self.time_len,3))#声音时长
            # 读取波形数据
            str_data = f.readframes(self.nframes)
            wave_data = np.fromstring(str_data, dtype=np.short)
            wave_data.shape = -1, self.nchannels
            self.wave_data = wave_data.T
            
    def FFT(self):
        yf = np.fft.fft(self.wave_data,self.nframes)# FFT
        bias =  (yf[:, 0] / self.nframes).real
        yf_amplitude = np.abs(yf)* (2.0/self.nframes)
        yf_amplitude[:, 0] = bias #直流分量(0 Hz处)修正
        self.yf_amplitude = yf_amplitude[:, 0:self.nframes//2]#有效信息只有一半
        #ts = pd.Series(self.yf_amplitude[0] * self.framerate / self.nframes)
        #ts.plot(figsize=(30,6))

    def plot(self):
        #self.freq = np.arange(0,self.nframes//2) * self.framerate / self.nframes #实际频率
        start = int(200 / (self.framerate / self.nframes)) # 人类最低频率
        end = int(1100 / (self.framerate / self.nframes))   # 人类发生最高频率
        human_rate = self.yf_amplitude[0][start:end]
        x = 0
        for i in range(len(human_rate)):
            #print(human_rate[i])
            if human_rate[i] >= 10.0:
                x = x+1
        #print(x)
        peo_label = 0
        if x >= 1600.0:
            label = 'people'
            #print(label)
        else:
            label = 'not people'
            #print(label)
        return label
  
        
if __name__ == "__main__":
    wav = Wav_FFT(wav_path='audio_wav_2/linkunling2/linkunling21583301748.wav')
    wav.read_wav()
    wav.FFT()
    result = wav.plot()
    print(result)


# In[92]:


import os
if __name__ == "__main__":
    #file_name = 'audio_wav/taifei' #62
    #file_name = 'audio_wav/xiefei' #54
    #file_name = 'audio_wav/surroundings2' 
    #file_name = 'audio_wav/linkunling' #65 42
    #file_name = 'audio_wav/liusong' #60
    file_name = 'audio_wav/suboss2' #70 37
    result_list = []
    for category in os.listdir(file_name):
        wav_path = os.path.join(file_name, category)
        wav = Wav_FFT(wav_path= wav_path)
        wav.read_wav()
        wav.FFT()
        label = wav.plot()
        result_list.append(label)
        #if label == 'people':
            #print(category, label)
    print(result_list)
    print(result_list.count('people')/len(os.listdir(file_name)), result_list.count('people'), len(os.listdir(file_name)))


# In[54]:


import matplotlib
import matplotlib.pyplot as plt
import numpy as np
import wave
from scipy import signal
import pandas as pd 

class Wav_delta_FFT(object):
    '''
    先过滤掉一定频率得音频部分，然后再对过滤过的音频做fft，然后再根据过滤后的音频判断其是否含有人类的声音，双重检验。
    '''
    def __init__(self, wav_path=''):
        self.path = wav_path
        
    def read_wav(self):
        with  wave.open(self.path, "rb") as f:
            parameters = f.getparams()
            self.nchannels, self.sampwidth, self.framerate, self.nframes = parameters[:4]
            self.time_len = self.nframes*1.0 / self.framerate #声音时长
            #print("声道数: ", self.nchannels) #声道数：可以是单声道或者是双声道
            #print("量化位数[byte]: ", self.sampwidth)#量化位数：一次采样所采集的数据的字节数
            #print("采样频率[Hz]: ", self.framerate) #采样频率：一秒内对声音信号的采集次数，常用的有8kHz, 16kHz, 32kHz, 48kHz, 11.025kHz, 22.05kHz, 44.1kHz
            #print("采样点数: ", self.nframes)#采样点数
            #print("声音时长[s]: ", round(self.time_len,3))#声音时长
            # 读取波形数据
            str_data = f.readframes(self.nframes)
            wave_data = np.fromstring(str_data, dtype=np.short)
            wave_data.shape = -1, self.nchannels
            self.wave_data = wave_data.T
    def delta(self):
        #b, a = signal.butter(2, [90 * 2 / 16000, 1200 * 2 / 16000], 'bandpass')
        b, a = signal.butter(2, [90 * 2 / 16000, 1100 * 2 / 16000], 'bandpass') ###90,1100可调参
        self.wave_data = np.reshape(self.wave_data,(self.wave_data.shape[1],))
        filtedData = signal.filtfilt(b, a, self.wave_data)
        self.wave_data = np.reshape(filtedData,(1,filtedData.shape[0]))
        print()            
    def FFT(self):
        '''
        求每hz的幅度,即各频率成分积累。
        '''
        yf = np.fft.fft(self.wave_data,self.nframes)# FFT
        bias =  (yf[:, 0] / self.nframes).real
        yf_amplitude = np.abs(yf)* (2.0/self.nframes)
        yf_amplitude[:, 0] = bias #直流分量(0 Hz处)修正
        self.yf_amplitude = yf_amplitude[:, 0:self.nframes//2]#有效信息只有一半
        #ts = pd.Series(self.yf_amplitude[0] * self.framerate / self.nframes)
        #ts.plot(figsize=(30,6))

    def plot(self):
        #self.freq = np.arange(0,self.nframes//2) * self.framerate / self.nframes #实际频率
        #ts = pd.Series(self.yf_amplitude[0] * self.framerate / self.nframes)
        #ts.plot(figsize=(30,6))
        #start = int(200 / (self.framerate / self.nframes)) # 人类最低频率 #200可调参
        start = int(200 / (self.framerate / self.nframes))
        end = int(1100 / (self.framerate / self.nframes))   # 人类发生最高频率 #1100，可调参
        #print(len(self.yf_amplitude[0]), start, end)
        human_rate = self.yf_amplitude[0][start:end]
        #print(len(human_rate))
        x = 0
        for i in range(len(human_rate)):
            #print(human_rate[i])
            if human_rate[i] >=10:#10可调参
                x = x+1
        peo_label = 0
        if x >= 1600.0:#1600可调参
            label = 'people'
            #print(label)
        else:
            label = 'not people'
            #print(label)
        return label
  
        
# if __name__ == "__main__":
#     wav = Wav_FFT(wav_path='audio_wav_2/linkunling2/linkunling21583301748.wav')
#     #wav = Wav_FFT(wav_path='audio_wav/surroundings/surrounding1su1578565858.wav')
#     #wav = Wav_FFT(wav_path='audio_wav_2/surroundings2/surroundings21583303827.wav')
#     wav.read_wav()
#     wav.delta()
#     wav.FFT()
#     wav.plot()


# In[55]:


import os
import warnings

warnings.filterwarnings('ignore')
if __name__ == "__main__":
    people_file_list = ['audio_wav/taifei', 'audio_wav/xiefei', 'audio_wav/linkunling2',
                 'audio_wav/linkunling', 'audio_wav/liusong','audio_wav/suboss',
                 'audio_wav/suboss2']
    surr_file_list = ['audio_wav/surroundings', 'audio_wav/surroundings2']
    #file_name = 'audio_wav/taifei' #62
    #file_name = 'audio_wav/xiefei' #54
    #file_name = 'audio_wav/surroundings' #94  95
    #file_name = 'audio_wav/linkunling2' #65 42
    #file_name = 'audio_wav/liusong' #60
    #file_name = 'audio_wav/suboss' #70 37
    #人声共390条音频，下面是测试人声的代码 
    result_num = []
    for file_name in people_file_list:
        result_list = []
        for category in os.listdir(file_name):
            wav_path = os.path.join(file_name, category)
            wav = Wav_delta_FFT(wav_path= wav_path)
            wav.read_wav()
            wav.FFT()
            label = wav.plot()
            result_list.append(label)
            #if label == 'people':
                #print(category, label)
        #print(result_list)
        result_num.append(result_list.count('people'))
        print(file_name, result_list.count('people')/len(os.listdir(file_name)), result_list.count('people'), len(os.listdir(file_name)))
    
    
    #环境共189条音频，下面是测试环境的代码
    result_num2 = []
    for file_name in surr_file_list:
        result_list = []
        for category in os.listdir(file_name):
            wav_path = os.path.join(file_name, category)
            wav = Wav_delta_FFT(wav_path= wav_path)
            wav.read_wav()
            wav.FFT()
            label = wav.plot()
            result_list.append(label)
            #if label == 'people':
                #print(category, label)
        #print(result_list)
        result_num2.append(result_list.count('not people'))
        print(file_name, result_list.count('not people')/len(os.listdir(file_name)), result_list.count('not people'), len(os.listdir(file_name)))
    print('---------------------------------------------')
    print('准确率：', sum(result_num)/397, result_num,sum(result_num))
    print('准确率：', sum(result_num2)/189)


# In[ ]:




